const { connectMongoDB, closeMongoDB } = require('./util')
const Neo4j = require("node-neo4j")

// 连接知识图谱
const connect = (ip, account, pass) => {
  return new Promise(resolve => {
    const neo = new Neo4j(`http://${account}:${pass}@${ip}:${7474}`)
    const cql = 'MATCH (N) RETURN N LIMIT 1'
    neo.cypherQuery(cql, (err, res) => {
      err || res == undefined ? resolve(undefined) : resolve(neo)
    })
  })
}

// 将知识图谱连接信息存入MongoDB
const saveNeo4jToMongoDB = (username, neo) => {
  return new Promise(async resolve => {
    const { client, dbo } = await connectMongoDB()
    const where = { username }
    dbo.collection('user').updateOne(where, {
      $set: {
        cg: {
          connector: neo,
          nodeTypes: [],
          relationTypes: []
        }
      }
    }).then(res => {
      resolve(res)
      closeMongoDB(client)
    })
  })
}

// 取出当前用户的知识图谱连接信息
const getNeo4jFromMongoDB = username => {
  return new Promise(async resolve => {
    const { client, dbo } = await connectMongoDB()
    const where = { username }
    dbo.collection('user').find(where).toArray((err, res) => {
      if (err) throw err
      resolve(res[0].cg.connector)
      closeMongoDB(client)
    })
  })
}

// 获取节点类型
const getNodeTypesByNeo4j = (neo) => {
  return new Promise(resolve => {
    const cql = 'MATCH (N) RETURN DISTINCT LABELS(N)'
    neo.cypherQuery(cql, (err, res) => {
      if (err) throw err
      const data = []
      for (let i = 0; i < res.data.length; i ++) {
        data.push(...res.data[i])
      }
      resolve([...new Set(data)])
    })
  })
}

// 获取关系类型
const getRelationTypesByNeo4j = (neo) => {
  return new Promise(resolve => {
    const cql = 'MATCH ()-[R]->() RETURN DISTINCT TYPE(R)'
    neo.cypherQuery(cql, (err, res) => {
      if (err) throw err
      const data = res.data.map(item => item)
      resolve(data)
    })
  })
}

// 将节点类型与关系类型存入MongoDB
const saveNodeAndRelationTypesToMongoDB = (username, nodeTypes, relationTypes) => {
  return new Promise(async resolve => {
    const { client, dbo } = await connectMongoDB()
    const where = { username }
    dbo.collection('user').updateOne(where, {
      $set: {
        "cg.nodeTypes": nodeTypes,
        "cg.relationTypes": relationTypes
      }
    }).then(() => {
      closeMongoDB(client)
      resolve()
    })
  })
}

module.exports = {
  connect, // 连接neo4j
  saveNeo4jToMongoDB, // 将当前连接的知识图谱连接器保存到mongodb
  getNeo4jFromMongoDB, // 从mongodb缓存中获取知识图谱连接器
  getNodeTypesByNeo4j, // 从知识图谱中获取节点类型
  getRelationTypesByNeo4j, // 从知识图谱中获取关系类型
  saveNodeAndRelationTypesToMongoDB, // 从知识图谱中同步节点类型与关系类型到MongoDB中
}